package net.xdclass.order.component.strategy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.common.constant.Cons;
import net.xdclass.common.enums.BizCodeEnum;
import net.xdclass.common.exception.BizException;
import net.xdclass.order.component.PayStrategy;
import net.xdclass.order.config.AliPayConfig;
import net.xdclass.order.config.PayUrlConfig;
import net.xdclass.order.enums.ClientType;
import net.xdclass.order.enums.ProductOrderPayTypeEnum;
import net.xdclass.order.model.vo.PayInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class AlipayStrategy implements PayStrategy {

    @Autowired
    private PayUrlConfig urlConfig;

    /**
     * 下单
     *
     * @param payInfo
     * @return 跳转地址【支付宝升级后返回的是一个地址，而不是一个html】
     */
    @Override
    public String unifiedOrder(PayInfoVO payInfo) {
        Map<String, String> param = new HashMap<>();
        param.put("out_trade_no", payInfo.getOutTradeNo());
        param.put("total_amount", String.valueOf(payInfo.getPayFee()));
        param.put("subject", payInfo.getTitle());
//        param.put("buyer_id", "123");
        Long orderPayTimeout = payInfo.getOrderPayTimeout();
        if (orderPayTimeout < 1){
            throw new BizException(BizCodeEnum.PAY_ORDER_PAY_TIMEOUT);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime plus = now.plus(orderPayTimeout, ChronoUnit.SECONDS);
        param.put("time_expire", formatter.format(plus));
        param.put("body", payInfo.getDescription());
        param.put("product_code", "FAST_INSTANT_TRADE_PAY");
        AlipayClient instance = AliPayConfig.instance();
        String redirectUrl = null;
        try {
            ClientType clientType = payInfo.getClientType();
            if (ClientType.H5.equals(clientType)){
                AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
                request.setNotifyUrl(urlConfig.getNotifyUrl());
                request.setReturnUrl(urlConfig.getReturnUrl());
                request.setBizContent(JSON.toJSONString(param));
                AlipayTradeWapPayResponse res = instance.pageExecute(request, "GET");
                if (res.isSuccess()){
                    redirectUrl = res.getBody();
                }else {
                    log.error("H5支付失败");
                }
            }
            if (ClientType.PC.equals(clientType)){
                AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
                request.setNotifyUrl(urlConfig.getNotifyUrl());
                request.setReturnUrl(urlConfig.getReturnUrl());
                request.setBizContent(JSON.toJSONString(param));
                AlipayTradePagePayResponse res = instance.pageExecute(request, "GET");
                if (res.isSuccess()){
                    redirectUrl = res.getBody();
                }else {
                    log.error("PC支付失败");
                }
            }
        }catch (AlipayApiException e){
            log.error("第三方支付失败【{}】", e);
        }
        return redirectUrl;
    }

    /**
     * 退款
     *
     * @param payinfo
     */
    @Override
    public String refund(PayInfoVO payinfo) {
        return PayStrategy.super.refund(payinfo);
    }

    /**
     * 查询订单状态
     *
     * @param payInfo
     * @return TRADE_SUCCESS | TRADE_CLOSED | TRADE_FINISHED
     */
    @Override
    public String queryPayState(PayInfoVO payInfo) {
        if (StringUtils.isEmpty(payInfo.getOutTradeNo())){
            return "";
        }
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        Map<String, String> bizContent = new HashMap<>();
        bizContent.put("out_trade_no", payInfo.getOutTradeNo());
        request.setBizContent(JSON.toJSONString(bizContent));
        AlipayTradeQueryResponse response;
        try {
            response = AliPayConfig.instance().execute(request);
            log.info("支付宝查询订单状态结果【{}】", response);
        } catch (AlipayApiException e) {
            log.warn("查询订单【{}】状态异常【{}】", payInfo.getOutTradeNo(), e.getErrMsg());
            return "";
        }
        if(response.isSuccess()){
            log.info("查询订单【{}】状态成功", payInfo.getOutTradeNo());
            return response.getTradeStatus();
        } else {
            log.warn("查询订单【{}】状态失败", payInfo.getOutTradeNo());
        }
        return "";
    }

    @Override
    public ProductOrderPayTypeEnum supportType() {
        return ProductOrderPayTypeEnum.ALIPAY;
    }
}
